package main

import (
	"Learn/main/chatroom/common/message"
	"encoding/json"
	"fmt"
	"io"
	"net"
)

// 根据客户端发送的消息种类不同，决定调用哪个函数来处理
func serverProcessMes(conn net.Conn, mes *message.Message) (err error) {
	switch mes.Type {
	case message.LoginMesType:
		err := serverProcessLogin(conn, mes)
		if err != nil {
			return err
		}
	// 处理登录请求

	case message.RegisterResMesType:

	default:
		fmt.Println("未知的消息类型 = ", mes.Type)
	}

	return err
}

// 处理登录请求
func serverProcessLogin(conn net.Conn, mes *message.Message) (err error) {
	// 先从 mes 中取出 mes.Data 并且序列化为LoginMes
	var loginMes message.LoginMes
	err = json.Unmarshal([]byte(mes.Data), &loginMes)
	if err != nil {
		fmt.Println("json.Unmarshal err = ", err)
		return err
	}
	// 先声明一个 resMes
	var resMes message.Message
	resMes.Type = message.LoginResMesType
	// 再声明一个 LoginResMsg
	var loginResMsg message.LoginResMsg
	// 如果用户的 ID 为 100，密码为 123456，那么就认为是正确的
	if loginMes.UserId == 100 && loginMes.UserPwd == "123456" {
		// 合法
		loginResMsg.Code = 200
		loginResMsg.Error = ""
	} else {
		// 不合法
		loginResMsg.Code = 500
		loginResMsg.Error = "登录失败，该用户不存在，请注册再使用"
	}
	// 将 LoginResMsg 序列化为 json 字符串
	data, err := json.Marshal(loginResMsg)
	if err != nil {
		fmt.Println("json.Marshal err = ", err)
		return err
	}
	resMes.Data = string(data)
	// 对 resMes 序列化为 json 字符串
	data, err = json.Marshal(resMes)
	if err != nil {
		fmt.Println("json.Marshal err = ", err)
		return err
	}
	// 发送数据
	err = writePkg(conn, data)
	return err
}

// 处理和客户端的通讯
func process(accept net.Conn) {
	// 这里需要延时关闭
	defer accept.Close()

	// 循环读取客户端发送的信息
	for {
		// 这里我们将读取数据包直接封装成一个函数 readPkg(), return Message,Err
		mes, err := readPkg(accept)
		if err != nil {
			if err == io.EOF {
				fmt.Println("客户端退出，服务器端也退出")
			} else {
				fmt.Println("conn.Read package err = ", err)
			}

			return
		}
		fmt.Println("收到的信息 = ", mes)

		err = serverProcessMes(accept, &mes)
		if err != nil {
			return
		}
	}
}

func main() {
	// 提示信息
	fmt.Println("服务器在 8889端口监听.....")
	listen, err := net.Listen("tcp", "0.0.0.0:8889")
	defer listen.Accept()
	if err != nil {
		fmt.Println("net.Listen err=", err)
		return
	}
	// 一旦监听成功，就等待客户端连接服务器
	for {
		fmt.Println("等待客户端连接服务器.....")
		accept, err := listen.Accept()
		if err != nil {
			fmt.Println("net.Accept err=", err)
		}
		// 一旦连接成功，则启动一个协程和客户端保持通讯
		go process(accept)
	}
}
